﻿using Consul;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Helpers
{
    public static class ConsulHelper
    {
        internal static IConsulClient ConsulClient { get; set; }

        /// <summary>
        /// 获取配置
        /// </summary>
        public static async Task<string> Get(string key)
        {
            var getPair = await ConsulClient.KV.Get(key).ConfigureAwait(false);
            return getPair.StatusCode == HttpStatusCode.NotFound ? null : Encoding.UTF8.GetString(getPair.Response.Value, 0, getPair.Response.Value.Length);
        }

        /// <summary>
        /// 设置配置
        /// </summary>
        public static async Task<bool> Set(string key, string value)
        {
            var putPair = new KVPair(key)
            {
                Value = Encoding.UTF8.GetBytes(value)
            };
            var putAttempt = await ConsulClient.KV.Put(putPair).ConfigureAwait(false);
            return putAttempt.Response;
        }

        /// <summary>
        /// 随机获取一个指定的服务地址
        /// </summary>
        public static async Task<string> GetRandomServiceAddr(string serviceName)
        {
            var services = await GetServiceAddrs(serviceName).ConfigureAwait(false);
            var service = services?.ElementAtOrDefault(Environment.TickCount % services.Count());
            return service;
        }

        /// <summary>
        /// 获取所有服务地址
        /// </summary>
        /// <param name="serviceName"></param>
        /// <returns></returns>
        public static async Task<IEnumerable<string>> GetServiceAddrs(string serviceName)
        {
            var response = (await ConsulClient.Agent.Services().ConfigureAwait(false)).Response;
            var services = response.Where(s => s.Value.Service.Equals(serviceName, StringComparison.OrdinalIgnoreCase)).Select(s => s.Value);
            if (services.Count() == 0) return null;
            var service = services.ElementAtOrDefault(Environment.TickCount % services.Count());
            return services.Select(x => $"{x.Address}:{x.Port}");
        }
    }
}
